using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System.Collections.Generic;
using System.Linq;
using SeataNet.Core.Common;
using SeataNet.Core.RPC;

namespace SeataNet.Core.Cluster
{
    /// <summary>
    /// 集群配置
    /// </summary>
    public class ClusterConfiguration
    {
        /// <summary>
        /// 是否启用集群模式
        /// </summary>
        public bool EnableClusterMode { get; set; } = false;

        /// <summary>
        /// 是否启用单节点模式
        /// </summary>
        public bool EnableSingleNodeMode { get; set; } = true;

        /// <summary>
        /// 节点端口
        /// </summary>
        public int Port { get; set; } = 8091;

        /// <summary>
        /// 节点优先级
        /// </summary>
        public int NodePriority { get; set; } = 1;

        /// <summary>
        /// 心跳间隔（秒）
        /// </summary>
        public int HeartbeatIntervalSeconds { get; set; } = 10;

        /// <summary>
        /// 健康检查间隔（秒）
        /// </summary>
        public int HealthCheckIntervalSeconds { get; set; } = 30;

        /// <summary>
        /// 选举检查间隔（秒）
        /// </summary>
        public int ElectionCheckIntervalSeconds { get; set; } = 60;

        /// <summary>
        /// 节点超时（秒）
        /// </summary>
        public int NodeTimeoutSeconds { get; set; } = 30;

        /// <summary>
        /// 是否启用节点发现
        /// </summary>
        public bool DiscoveryEnabled { get; set; } = true;

        /// <summary>
        /// 已知节点列表
        /// </summary>
        public List<string> KnownNodes { get; set; } = new List<string>();

        /// <summary>
        /// 最大重试次数
        /// </summary>
        public int MaxRetryAttempts { get; set; } = 3;

        /// <summary>
        /// 连接超时（毫秒）
        /// </summary>
        public int ConnectionTimeoutMilliseconds { get; set; } = 5000;

        /// <summary>
        /// 请求超时（毫秒）
        /// </summary>
        public int RequestTimeoutMilliseconds { get; set; } = 30000;

        /// <summary>
        /// 是否启用SSL
        /// </summary>
        public bool EnableSsl { get; set; } = false;

        /// <summary>
        /// SSL证书路径
        /// </summary>
        public string? SslCertificatePath { get; set; }

        /// <summary>
        /// SSL证书密码
        /// </summary>
        public string? SslCertificatePassword { get; set; }
    }

    /// <summary>
    /// 集群配置验证器
    /// </summary>
    public class ClusterConfigurationValidator : IValidateOptions<ClusterConfiguration>
    {
        public ValidateOptionsResult Validate(string? name, ClusterConfiguration options)
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }
            
            var failures = new List<string>();

            // 验证端口
            if (options.Port <= 0 || options.Port > 65535)
            {
                failures.Add($"Port must be between 1 and 65535, but was {options.Port}");
            }

            // 验证节点优先级
            if (options.NodePriority < 0)
            {
                failures.Add($"NodePriority must be non-negative, but was {options.NodePriority}");
            }

            // 验证心跳间隔
            if (options.HeartbeatIntervalSeconds <= 0)
            {
                failures.Add($"HeartbeatIntervalSeconds must be positive, but was {options.HeartbeatIntervalSeconds}");
            }

            // 验证健康检查间隔
            if (options.HealthCheckIntervalSeconds <= 0)
            {
                failures.Add($"HealthCheckIntervalSeconds must be positive, but was {options.HealthCheckIntervalSeconds}");
            }

            // 验证选举检查间隔
            if (options.ElectionCheckIntervalSeconds <= 0)
            {
                failures.Add($"ElectionCheckIntervalSeconds must be positive, but was {options.ElectionCheckIntervalSeconds}");
            }

            // 验证节点超时
            if (options.NodeTimeoutSeconds <= 0)
            {
                failures.Add($"NodeTimeoutSeconds must be positive, but was {options.NodeTimeoutSeconds}");
            }

            // 验证最大重试次数
            if (options.MaxRetryAttempts < 0)
            {
                failures.Add($"MaxRetryAttempts must be non-negative, but was {options.MaxRetryAttempts}");
            }

            // 验证连接超时
            if (options.ConnectionTimeoutMilliseconds <= 0)
            {
                failures.Add($"ConnectionTimeoutMilliseconds must be positive, but was {options.ConnectionTimeoutMilliseconds}");
            }

            // 验证请求超时
            if (options.RequestTimeoutMilliseconds <= 0)
            {
                failures.Add($"RequestTimeoutMilliseconds must be positive, but was {options.RequestTimeoutMilliseconds}");
            }

            // 验证SSL配置
            if (options.EnableSsl)
            {
                if (string.IsNullOrEmpty(options.SslCertificatePath))
                {
                    failures.Add("SslCertificatePath must be specified when EnableSsl is true");
                }
            }

            return failures.Any()
                ? ValidateOptionsResult.Fail(failures)
                : ValidateOptionsResult.Success;
        }
    }

    /// <summary>
    /// 集群服务集合扩展
    /// </summary>
    public static class ClusterServiceCollectionExtensions
    {
        /// <summary>
        /// 添加集群支持
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="configuration">集群配置</param>
        /// <returns>服务集合</returns>
        public static IServiceCollection AddCluster(
            this IServiceCollection services,
            Action<ClusterConfiguration>? configuration = null)
        {
            // 添加配置
            if (configuration != null)
            {
                services.Configure(configuration);
            }
            else
            {
                services.Configure<ClusterConfiguration>(options =>
                {
                    // 默认配置
                    options.EnableClusterMode = false;
                    options.EnableSingleNodeMode = true;
                    options.Port = 8091;
                    options.NodePriority = 1;
                    options.HeartbeatIntervalSeconds = 10;
                    options.HealthCheckIntervalSeconds = 30;
                    options.ElectionCheckIntervalSeconds = 60;
                    options.NodeTimeoutSeconds = 30;
                    options.DiscoveryEnabled = true;
                    options.KnownNodes = new List<string>();
                    options.MaxRetryAttempts = 3;
                    options.ConnectionTimeoutMilliseconds = 5000;
                    options.RequestTimeoutMilliseconds = 30000;
                    options.EnableSsl = false;
                });
            }

            // 添加配置验证
            services.AddSingleton<IValidateOptions<ClusterConfiguration>, ClusterConfigurationValidator>();

            // 添加负载均衡配置
            services.Configure<LoadBalanceConfiguration>(options =>
            {
                options.Strategy = LoadBalanceStrategy.RoundRobin;
                options.DefaultWeight = 1;
                options.EnableHealthCheck = true;
                options.HealthCheckIntervalSeconds = 30;
                options.FailureThreshold = 3;
                options.RecoveryThreshold = 2;
            });

            // 添加故障转移配置
            services.Configure<FailoverConfiguration>(options =>
            {
                options.Strategy = FailoverStrategy.Failover;
                options.MaxRetryAttempts = 3;
                options.RetryDelayMilliseconds = 1000;
                options.NodeRecoveryTimeoutSeconds = 300;
                options.RecoveryCheckIntervalSeconds = 60;
                options.EnableFallback = false;
                options.FallbackTimeoutMilliseconds = 5000;
            });

            // 注册核心服务
            services.AddSingleton<IClusterManager, DefaultClusterManager>();
            services.AddSingleton<ILoadBalancer, DefaultLoadBalancer>();
            services.AddSingleton<IFailoverManager, DefaultFailoverManager>();

            // 注册初始化服务
            services.AddSingleton<IHostedService, ClusterInitializationService>();

            return services;
        }

        /// <summary>
        /// 添加集群节点
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="nodeAddress">节点地址</param>
        /// <returns>服务集合</returns>
        public static IServiceCollection AddClusterNode(
            this IServiceCollection services,
            string nodeAddress)
        {
            services.Configure<ClusterConfiguration>(options =>
            {
                if (!options.KnownNodes.Contains(nodeAddress))
                {
                    options.KnownNodes.Add(nodeAddress);
                }
            });

            return services;
        }

        /// <summary>
        /// 添加集群节点列表
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="nodeAddresses">节点地址列表</param>
        /// <returns>服务集合</returns>
        public static IServiceCollection AddClusterNodes(
            this IServiceCollection services,
            IEnumerable<string> nodeAddresses)
        {
            services.Configure<ClusterConfiguration>(options =>
            {
                foreach (var address in nodeAddresses)
                {
                    if (!options.KnownNodes.Contains(address))
                    {
                        options.KnownNodes.Add(address);
                    }
                }
            });

            return services;
        }

        /// <summary>
        /// 配置负载均衡策略
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="strategy">负载均衡策略</param>
        /// <returns>服务集合</returns>
        public static IServiceCollection ConfigureLoadBalanceStrategy(
            this IServiceCollection services,
            LoadBalanceStrategy strategy)
        {
            services.Configure<LoadBalanceConfiguration>(options =>
            {
                options.Strategy = strategy;
            });

            return services;
        }

        /// <summary>
        /// 配置故障转移策略
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="strategy">故障转移策略</param>
        /// <returns>服务集合</returns>
        public static IServiceCollection ConfigureFailoverStrategy(
            this IServiceCollection services,
            FailoverStrategy strategy)
        {
            services.Configure<FailoverConfiguration>(options =>
            {
                options.Strategy = strategy;
            });

            return services;
        }

        /// <summary>
        /// 启用SSL
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="certificatePath">证书路径</param>
        /// <param name="certificatePassword">证书密码</param>
        /// <returns>服务集合</returns>
        public static IServiceCollection EnableSsl(
            this IServiceCollection services,
            string certificatePath,
            string? certificatePassword = null)
        {
            services.Configure<ClusterConfiguration>(options =>
            {
                options.EnableSsl = true;
                options.SslCertificatePath = certificatePath;
                options.SslCertificatePassword = certificatePassword;
            });

            return services;
        }

        /// <summary>
        /// 配置心跳间隔
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="intervalSeconds">间隔秒数</param>
        /// <returns>服务集合</returns>
        public static IServiceCollection ConfigureHeartbeatInterval(
            this IServiceCollection services,
            int intervalSeconds)
        {
            services.Configure<ClusterConfiguration>(options =>
            {
                options.HeartbeatIntervalSeconds = intervalSeconds;
            });

            return services;
        }

        /// <summary>
        /// 配置健康检查间隔
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="intervalSeconds">间隔秒数</param>
        /// <returns>服务集合</returns>
        public static IServiceCollection ConfigureHealthCheckInterval(
            this IServiceCollection services,
            int intervalSeconds)
        {
            services.Configure<ClusterConfiguration>(options =>
            {
                options.HealthCheckIntervalSeconds = intervalSeconds;
            });

            return services;
        }

        /// <summary>
        /// 配置选举检查间隔
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="intervalSeconds">间隔秒数</param>
        /// <returns>服务集合</returns>
        public static IServiceCollection ConfigureElectionCheckInterval(
            this IServiceCollection services,
            int intervalSeconds)
        {
            services.Configure<ClusterConfiguration>(options =>
            {
                options.ElectionCheckIntervalSeconds = intervalSeconds;
            });

            return services;
        }

        /// <summary>
        /// 配置节点超时
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="timeoutSeconds">超时秒数</param>
        /// <returns>服务集合</returns>
        public static IServiceCollection ConfigureNodeTimeout(
            this IServiceCollection services,
            int timeoutSeconds)
        {
            services.Configure<ClusterConfiguration>(options =>
            {
                options.NodeTimeoutSeconds = timeoutSeconds;
            });

            return services;
        }

        /// <summary>
        /// 配置最大重试次数
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="maxRetryAttempts">最大重试次数</param>
        /// <returns>服务集合</returns>
        public static IServiceCollection ConfigureMaxRetryAttempts(
            this IServiceCollection services,
            int maxRetryAttempts)
        {
            services.Configure<ClusterConfiguration>(options =>
            {
                options.MaxRetryAttempts = maxRetryAttempts;
            });

            return services;
        }

        /// <summary>
        /// 配置连接超时
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="timeoutMilliseconds">超时毫秒数</param>
        /// <returns>服务集合</returns>
        public static IServiceCollection ConfigureConnectionTimeout(
            this IServiceCollection services,
            int timeoutMilliseconds)
        {
            services.Configure<ClusterConfiguration>(options =>
            {
                options.ConnectionTimeoutMilliseconds = timeoutMilliseconds;
            });

            return services;
        }

        /// <summary>
        /// 配置请求超时
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="timeoutMilliseconds">超时毫秒数</param>
        /// <returns>服务集合</returns>
        public static IServiceCollection ConfigureRequestTimeout(
            this IServiceCollection services,
            int timeoutMilliseconds)
        {
            services.Configure<ClusterConfiguration>(options =>
            {
                options.RequestTimeoutMilliseconds = timeoutMilliseconds;
            });

            return services;
        }
    }

    /// <summary>
    /// 集群初始化服务
    /// </summary>
    public class ClusterInitializationService : IHostedService
    {
        private readonly ILogger<ClusterInitializationService> _logger;
        private readonly IClusterManager _clusterManager;
        private readonly ILoadBalancer _loadBalancer;
        private readonly IFailoverManager _failoverManager;
        private readonly IOptionsMonitor<ClusterConfiguration> _configuration;

        public ClusterInitializationService(
            ILogger<ClusterInitializationService> logger,
            IClusterManager clusterManager,
            ILoadBalancer loadBalancer,
            IFailoverManager failoverManager,
            IOptionsMonitor<ClusterConfiguration> configuration)
        {
            _logger = logger;
            _clusterManager = clusterManager;
            _loadBalancer = loadBalancer;
            _failoverManager = failoverManager;
            _configuration = configuration;
        }

        public async Task StartAsync(CancellationToken cancellationToken)
        {
            _logger.LogInformation("Starting cluster initialization service");

            var config = _configuration.CurrentValue;

            if (config.EnableClusterMode || config.EnableSingleNodeMode)
            {
                try
                {
                    // 启动集群管理器
                    await _clusterManager.StartAsync(cancellationToken);

                    // 启动故障转移管理器
                    await _failoverManager.StartAsync(cancellationToken);

                    _logger.LogInformation("Cluster initialization service started successfully");
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "Error starting cluster initialization service");
                    throw;
                }
            }
            else
            {
                _logger.LogInformation("Cluster mode is disabled, skipping cluster initialization");
            }
        }

        public async Task StopAsync(CancellationToken cancellationToken)
        {
            _logger.LogInformation("Stopping cluster initialization service");

            try
            {
                // 停止故障转移管理器
                await _failoverManager.StopAsync(cancellationToken);

                // 停止集群管理器
                await _clusterManager.StopAsync(cancellationToken);

                _logger.LogInformation("Cluster initialization service stopped successfully");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error stopping cluster initialization service");
            }
        }
    }
}